#include "task_manager.h"

/* 按键 + 菜单扫描任务 */
void ScanKeyTask(void)
{
    cotKey_Scan(HAL_GetTick());
    cotMenu_Task();
}

/* LED扫描任务 */
void ScanLedTask(void)
{
    cotLed_Ctrl(HAL_GetTick());
}

/* 报警任务 */
void ScanAlertTask(void)
{
    ALERT_Scan(HAL_GetTick());
}

/* 音乐任务 */
void ScanMusicTask(void)
{
    MUSIC_Scan(HAL_GetTick());
}

/* 调度测试任务 */
void TestScheduleTask(void)
{
    static uint32_t counter = 0;
    static uint32_t lastTime = 0;
    uint32_t currentTime = HAL_GetTick();
    counter++;
    printf("Task executed: %ld, interval: %ldms\r\n", counter, currentTime - lastTime);
    lastTime = currentTime;
}

/* ADC测试任务 */
void InitADCTest(void)
{
    adc_nch_dma_init((uint32_t)&g_adc_dma_buf); /* 初始化多通道ADC DMA采集 */
    adc_nch_dma_enable(ADC_DMA_BUF_SIZE);       /* 启动ADC DMA多通道采集 */
}

void ScanADCTask(void)
{
    char buf[30]; /* 字符缓冲区 */
    
    /* 调用BSP中的ADC数据处理函数，函数内部会判断是否有新数据 */
    if (0 == adc_process_data()) /* 如果返回0，表示没有新数据 */
    {
        return;   /* 没有新数据，直接返回 */
    }
    
    /* 显示VDDA电压值 */
    sprintf(buf, "VDDA: %.3fV ", g_vdda_voltage);
    LCD_ShowString(30, 10, (const uint8_t *)buf, RED, g_back_color, 16, 0);
    
    /* 循环显示通道0~通道3和通道10~通道13的结果 */
    for(uint8_t j = 0; j < 8; j++)  /* 遍历8个通道 */
    {
        /* 显示结果 */
        if (j < 4) 
        {
            /* 通道0~3：显示为电压值(V) */
            sprintf(buf, "CH%d: Base V %.3fV ", j, g_adc_voltages[j]);
            LCD_ShowString(30, 36 + (j * 42), (const uint8_t *)buf, BLUE, g_back_color, 16, 0);
            
            sprintf(buf, "CH%d: Real V %.2fV ", j, g_actual_values[j]);
            LCD_ShowString(30, 52 + (j * 42), (const uint8_t *)buf, BLUE, g_back_color, 16, 0);
        } 
        else 
        {
            /* 通道10~13：显示为电流值(mA) */
            uint8_t ch_num = j + 6; /* j+6表示通道10~13 */
            sprintf(buf, "CH%d: Base V %.3fV ", ch_num, g_adc_voltages[j]);
            LCD_ShowString(30, 36 + (j * 42), (const uint8_t *)buf, BLUE, g_back_color, 16, 0);
            
            sprintf(buf, "CH%d: Current %.2fmA ", ch_num, g_actual_values[j]);
            LCD_ShowString(30, 52 + (j * 42), (const uint8_t *)buf, BLUE, g_back_color, 16, 0);
        }
    }
}

/* DAC测试任务 */
void InitDACTest(void)
{
    dac_init(1);    /* 初始化DAC1_OUT1通道 1:DAC_OUT_1-PA4  2:DAC_OUT_2-PA5 */
    dac_init(2);    /* 初始化DAC1_OUT2通道 1:DAC_OUT_1-PA4  2:DAC_OUT_2-PA5 */
}

void ScanDACTask(void)
{
    uint16_t adcx;
    float temp;
    char buf[30]; /* 字符缓冲区 */
    
    /* 读取DAC通道1的当前设置值 */
    adcx = HAL_DAC_GetValue(&g_dac_handle, DAC_CHANNEL_1); /* 读取前面设置DAC1_OUT1的值 */
    sprintf(buf, "DAC1 Value: %4d", adcx);
    LCD_ShowString(30, 414, (const uint8_t *)buf, RED, g_back_color, 16, 0);

    /* 计算对应的电压值 */
    temp = (float)adcx * (g_vdda_voltage / 4096);                      /* 得到DAC电压值 */
    sprintf(buf, "DAC1 Vol: %.2fV ", temp);
    LCD_ShowString(30, 430, (const uint8_t *)buf, RED, g_back_color, 16, 0);

    /* 计算对应的电流值 - 使用1V对应10mA的关系 */
    /* 电流计算公式：电流(mA) = 10 * 电压值(V) */
    float current = 10.0f * temp;
    sprintf(buf, "DAC1 Current: %.2fmA ", current);
    LCD_ShowString(30, 446, (const uint8_t *)buf, RED, g_back_color, 16, 0);
}

/* PWM DAC测试任务 */
void InitPWMDAC_Test(void)
{
    pwmdac_init(256 - 1, 32 - 1);               /* PWM DAC初始化, Fpwm = 168MHz/((255+1)*(31+1)) = 20.51KHz，适配GP8101 */
}

void ScanPWMDACTask(void)
{
    uint16_t ccr_value;
    float duty;
    char buf[30]; /* 字符缓冲区 */
    
    /* 显示PWMDAC1输出信息 */
    ccr_value = __HAL_TIM_GET_COMPARE(&g_tim1_handler, PWMDAC1_TIMX_CHY);   /* PWMDAC1 定时器输出比较值 */
    sprintf(buf, "PWMDAC1 CCR: %4d", ccr_value);
    LCD_ShowString(30, 414, (const uint8_t *)buf, RED, g_back_color, 16, 0);

    /* 计算对应的占空比 */
    duty = (float)ccr_value * 100 / (g_tim1_handler.Init.Period + 1);
    sprintf(buf, "PWMDAC1 Duty: %.1f%% ", duty);
    LCD_ShowString(30, 430, (const uint8_t *)buf, RED, g_back_color, 16, 0);
    
    /* 显示预期输出电压（GP8101输出范围是0-10V） */
    sprintf(buf, "Output V: %.2fV", duty * 0.1f); /* 10V * duty/100 */
    LCD_ShowString(30, 446, (const uint8_t *)buf, RED, g_back_color, 16, 0);
}

/* 监控任务 */
void ScanMonitorTask(void)
{
    char buf[30]; /* 字符缓冲区 */
    
    /* 调用BSP中的ADC数据处理函数，函数内部会判断是否有新数据 */
    if (0 == adc_process_data()) /* 如果返回0，表示没有新数据 */
    {
        return;   /* 没有新数据，直接返回 */
    }
    
    /* 显示电压输入通道 (CH0-CH3) */
    for(uint8_t j = 0; j < 4; j++)
    {
        sprintf(buf, "CH%d: %.2fV ", j, g_actual_values[j]);
        LCD_ShowString(30, j * 32, (const uint8_t *)buf, BLUE, g_back_color, 32, 0);
    }
    
    /* 显示电流输入通道 (CH10-CH13) */
    for(uint8_t j = 4; j < 8; j++)
    {
        uint8_t ch_num = j + 6; /* j+6表示通道10~13 */
        sprintf(buf, "CH%d: %.2fmA ", ch_num, g_actual_values[j]);
        LCD_ShowString(30, j * 32, (const uint8_t *)buf, BLUE, g_back_color, 32, 0);
    }
    
    /* 输入和输出通道之间空一行 */
    
    /* 显示电压输出 - PWMDAC1 */
    float voltage1 = ChannelOutput_GetActualOutput(1);
    sprintf(buf, "PWMDAC1: %.2fV ", voltage1);
    LCD_ShowString(30, (8 + 1) * 32, (const uint8_t *)buf, RED, g_back_color, 32, 0);
    
    /* 显示电压输出 - PWMDAC2 */
    float voltage2 = ChannelOutput_GetActualOutput(2);
    sprintf(buf, "PWMDAC2: %.2fV ", voltage2);
    LCD_ShowString(30, (9 + 1) * 32, (const uint8_t *)buf, RED, g_back_color, 32, 0);
    
    /* 显示电流输出 - DAC1 */
    float current1 = ChannelOutput_GetActualOutput(5);
    sprintf(buf, "DAC1: %.2fmA ", current1);
    LCD_ShowString(30, (10 + 1) * 32, (const uint8_t *)buf, RED, g_back_color, 32, 0);
    
    /* 显示电流输出 - DAC2 */
    float current2 = ChannelOutput_GetActualOutput(6);
    sprintf(buf, "DAC2: %.2fmA ", current2);
    LCD_ShowString(30, (11 + 1) * 32, (const uint8_t *)buf, RED, g_back_color, 32, 0);
    
    /* 显示电流输出 - PWMDAC3 */
    float current3 = ChannelOutput_GetActualOutput(7);
    sprintf(buf, "PWMDAC3: %.2fmA ", current3);
    LCD_ShowString(30, (12 + 1) * 32, (const uint8_t *)buf, RED, g_back_color, 32, 0);
    
    /* 显示电流输出 - PWMDAC4 */
    float current4 = ChannelOutput_GetActualOutput(8);
    sprintf(buf, "PWMDAC4: %.2fmA ", current4);
    LCD_ShowString(30, (13 + 1) * 32, (const uint8_t *)buf, RED, g_back_color, 32, 0);
}

/* 24CXX测试任务 */
void AT24CXXTest(void)
{
    at24cxx_safe_test();
}

/* NORFLASH测试任务 */
void NorflashTest(void)
{
    norflash_test();
}

/* RS485测试任务 */
void RS485_1SendTask(void)
{
    static uint8_t i = 0;
    static uint8_t cnt = 0;
    uint8_t rs485buf[5];
  
    /* 显示计数 */
    LCD_ShowString(30, 50, (const uint8_t *)"Count:", RED, g_back_color, 16, 0);
    LCD_ShowIntNum(30 + 48, 50, cnt, 3, g_point_color, g_back_color, 16);

    /* 显示发送数据 */
    LCD_ShowString(30, 70, (const uint8_t *)"Send Data:", RED, g_back_color, 16, 0);
    
    for (i = 0; i < 5; i++)
    {
        rs485buf[i] = cnt + i;        /* 填充发送缓冲区 */
        LCD_ShowIntNum(30 + i * 32, 90, rs485buf[i], 3, g_point_color, g_back_color, 16);    /* 显示数据 */
    }

    rs485_1_send_data(rs485buf, 5);   /* 发送5个字节 */
    
    cnt++;
}

void RS485_1ReceiveTask(void)
{
    static uint8_t i = 0;
    uint8_t rs485buf[5];
    uint8_t len = 0;  
    
    /* 显示接收数据 */
    LCD_ShowString(30, 110, (const uint8_t *)"Receive Data:", RED, g_back_color, 16, 0);
    
    rs485_1_receive_data(rs485buf, &len); /* 使用局部变量len来接收数据长度 */

    if (len)                              /* 接收到有数据 */
    {
        if (len > 5) len = 5;             /* 最大是5个数据 */

        for (i = 0; i < len; i++)
        {
            LCD_ShowIntNum(30 + i * 32, 130, rs485buf[i], 3, g_point_color, g_back_color, 16);    /* 显示数据 */
        }
    }
}

void RS485_2SendTask(void)
{
    static uint8_t i = 0;
    static uint8_t cnt = 0;
    uint8_t rs485buf[5];
    
    /* 显示计数 */
    LCD_ShowString(30, 150, (const uint8_t *)"Count:", RED, g_back_color, 16, 0);
    LCD_ShowIntNum(30 + 48, 150, cnt, 3, g_point_color, g_back_color, 16);
    
    /* 显示发送数据 */
    LCD_ShowString(30, 170, (const uint8_t *)"Send Data:", RED, g_back_color, 16, 0);
    
    for (i = 0; i < 5; i++)
    {
        rs485buf[i] = cnt + i;        /* 填充发送缓冲区 */
        LCD_ShowIntNum(30 + i * 32, 190, rs485buf[i], 3, g_point_color, g_back_color, 16);    /* 显示数据 */
    }

    rs485_2_send_data(rs485buf, 5);   /* 发送5个字节 */
    cnt++;
}

void RS485_2ReceiveTask(void)
{
    static uint8_t i = 0;
    uint8_t rs485buf[5]; 
    uint8_t len = 0;  
    
    /* 显示接收数据标题 */
    LCD_ShowString(30, 210, (const uint8_t *)"Receive Data:", RED, g_back_color, 16, 0);
    
    rs485_2_receive_data(rs485buf, &len); /* 使用局部变量len来接收数据长度 */

    if (len)                              /* 接收到有数据 */
    {
        if (len > 5) len = 5;             /* 最大是5个数据 */

        for (i = 0; i < len; i++)
        {
            LCD_ShowIntNum(30 + i * 32, 230, rs485buf[i], 3, g_point_color, g_back_color, 16);    /* 显示数据 */
        }
    }
}

void RS485_3SendTask(void)
{
    static uint8_t i = 0;
    static uint8_t cnt = 0;
    uint8_t rs485buf[5];
    
    /* 显示计数 */
    LCD_ShowString(30, 250, (const uint8_t *)"Count:", RED, g_back_color, 16, 0);
    LCD_ShowIntNum(30 + 48, 250, cnt, 3, g_point_color, g_back_color, 16);
    
    /* 显示发送数据 */
    LCD_ShowString(30, 270, (const uint8_t *)"Send Data:", RED, g_back_color, 16, 0);
    
    for (i = 0; i < 5; i++)
    {
        rs485buf[i] = cnt + i;        /* 填充发送缓冲区 */
        LCD_ShowIntNum(30 + i * 32, 290, rs485buf[i], 3, g_point_color, g_back_color, 16);    /* 显示数据 */
    }

    rs485_3_send_data(rs485buf, 5);   /* 发送5个字节 */
    cnt++;
}

void RS485_3ReceiveTask(void)
{
    static uint8_t i = 0;
    uint8_t rs485buf[5];
    uint8_t len = 0;  
    
    /* 显示接收数据标题 */
    LCD_ShowString(30, 310, (const uint8_t *)"Receive Data:", RED, g_back_color, 16, 0);
    
    rs485_3_receive_data(rs485buf, &len); /* 使用局部变量len来接收数据长度 */

    if (len)                              /* 接收到有数据 */
    {
        if (len > 5) len = 5;             /* 最大是5个数据 */

        for (i = 0; i < len; i++)
        {
            LCD_ShowIntNum(30 + i * 32, 330, rs485buf[i], 3, g_point_color, g_back_color, 16);    /* 显示数据 */
        }
    }
}
